#pragma once

#include <mutex>
#include <string>
#include <vector>

namespace ikvm
{

/*
 * @class Video
 * @brief Sets up the V4L2 video device and performs read operations
 */
class Video
{
	public:
		/*
		 * @brief Constructs Video object
		 *
		 * @param[in] p     - Path to the V4L2 video device
		 * @param[in] input - Reference to the Input object
		 * @param[in] fr    - desired frame rate of the video
		 */
		Video(const std::string& p , int fr = 30, int sub = 0, int w= 1920, int h =1080);
		~Video();
		Video(const Video&) = default;
		Video& operator=(const Video&) = default;
		Video(Video&&) = default;
		Video& operator=(Video&&) = default;

		/*
		 * @brief Gets the video frame data
		 *
		 * @return Pointer to the video frame data
		 */
		char* getData(int index);
		/* @brief Performs read to grab latest video frame */
		int getFrame();

		void freeFrame(int index);
		/*
		 * @brief Gets whether or not the video frame needs to be resized
		 *
		 * @return Boolean indicating if the frame needs to be resized
		 */
		bool needsResize();
		/* @brief Performs the resize and re-allocates framebuffer */
		void resize();
		/* @brief Starts streaming from the video device */
		int start();
		/* @brief Stops streaming from the video device */
		void stop();
		/* @brief Restarts streaming from the video device */
		void restart()
		{
		    stop();
		    start();
		}
		/*
		 * @brief Gets the subsampling of the video frame
		 *
		 * @return Value of the subsampling of video frame, 1:420/0:444
		 */
		inline int getSubsampling() const
		{
		    return subSampling;
		}
		/*
		 * @brief Sets the subsampling of the video frame
		 *
		 * @return Value of the subsampling of video frame, 1:420/0:444
		 */
		inline void setSubsampling(int _sub)
		{
		    subSampling = _sub;
		}
		int getFrameRate() ;
		unsigned int getFrameSize();
		unsigned int getHeight();
		unsigned int getWidth();
		/* @brief Number of bits per component of a pixel */
		static const int bitsPerSample;
		/* @brief Number of bytes of storage for a pixel */
		static const int bytesPerPixel;
		/* @brief Number of components in a pixel (i.e. 3 for RGB pixel) */
		static const int samplesPerPixel;

	  private:
		bool resizeAfterOpen;		
		int timingsError;		
		int fd;		
		int frameRate;	
		int lastFrameIndex;
		int height;	
		int width;					
		int subSampling;						
		std::string path;		
		void * pDevice;		
		void *hw ;
		void _stop();
};

} // namespace ikvm
